package com.zlw.main.audioeffects.utils;

//Gionee zhangjc 2013-05-15 added lrc function CR00808250 begin

import android.content.Context;
import android.os.Environment;
import android.os.storage.StorageManager;
import android.util.Log;


import com.zlw.main.audioeffects.base.MyApp;
import com.zlw.main.audioeffects.bean.LrcLine;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import info.monitorenter.cpdetector.io.ASCIIDetector;
import info.monitorenter.cpdetector.io.ByteOrderMarkDetector;
import info.monitorenter.cpdetector.io.CodepageDetectorProxy;
import info.monitorenter.cpdetector.io.JChardetFacade;
import info.monitorenter.cpdetector.io.ParsingDetector;
import info.monitorenter.cpdetector.io.UnicodeDetector;


public class LrcUtil {
    public static final String PREFIX = "gnmusic_increment=";
    public static final String CONFIG_SEPARATOR = "\r\n";
    //Gionee <hongsq> <2016-12-10> modify for <40710> begin
	public static final String LRC_PATH_OVERSEA =  "/" + Environment.DIRECTORY_MUSIC + "/" + "lrc";
    private static final String DEFAULT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
	//Gionee <hongsq> <2016-12-10> modify for <40710> end
    //convert str like [00:12.33] to long value
    public static long strToSecs(String s){
        long res =-1;//0;
        try {
            int p1 = s.indexOf(':');
            //if(p1 >=2){
                //String minStr = s.substring(p1 -2,p1);
                String minStr = s.substring(1,p1);
                res += Integer.parseInt(minStr) * 60;
                String secStr = s.substring(p1+1 ,p1+3);
                res += Integer.parseInt(secStr);
            //}
            
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }
        return res;
    }

    public static long strToMillisecond(String s) {
        long res =-1;//0;
        try {
            int p1 = s.indexOf(':');
            //if(p1 >=2){
            //String minStr = s.substring(p1 -2,p1);
            String minStr = s.substring(1,p1);
            res += Integer.parseInt(minStr) * 60 * 1000;
            String secStr = s.substring(p1+1 ,p1+3);
            res += Integer.parseInt(secStr) * 1000;
            String millSecStr = s.substring(p1+4);
            res += Integer.parseInt(millSecStr);
            //}

        } catch (Throwable e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }
        return res;
    }
    
    // Gionee <zhangjc><2013-09-02> modify for CR00874470 begin
    public static List<String> getTimeList(String s){
        List<String> res =  new ArrayList<String>();
        int start =0;
        int i =0, j= 0;
        while(i >=0 && j >=0){
            i = s.indexOf('[', start);
            j = s.indexOf(']', start);
            start = j +1;
            if(i>=0 && j>i)
                res.add(s.substring(i,j));
            else
                start = i+1;
        }
        return res;
    }
    // Gionee <zhangjc><2013-09-02> modify for CR00874470 emd
    public static void getLinesFromFileWithTime(int fileId, List<LrcLine> list){
//        List<LrcLine> list = new ArrayList<LrcLine>();
        InputStream fileInputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            fileInputStream = MyApp.getInstance().getResources().openRawResource(fileId);
            fileInputStream.markSupported();
            inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String lineTxt = null;
            while((lineTxt = bufferedReader.readLine()) != null){
                //list.add(lineTxt);
                if(lineTxt.length() > 0){
                    List<String> timeList = getTimeList(lineTxt);
                    String s = lineTxt.substring(lineTxt.lastIndexOf(']')+1);
                    if(s == null || s.length() == 0) {
                        s = "";
                    }
                    s = s.trim();
                    s = getLrcWithoutTrcTag(s);
                    int i =0;
                    for(i =0; i < timeList.size(); i++){
                        String strTime = timeList.get(i);
                        long time = strToSecs(strTime);
                        long millTime = strToMillisecond(strTime);
                        if (time >= 0) {
                            LrcLine ll = new LrcLine();
                            Log.i("lipeineng", "i " + i + "; millTime " + millTime + "; s " + s + "; " + strTime);
                            ll.setPos(time);
                            ll.setMillPos(millTime);
                            ll.setLrcStr(s);
                            list.add(ll);
                        }
                    }
                }
            }
        } catch (UnsupportedEncodingException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(bufferedReader != null){
                    bufferedReader.close();
                }

                if(inputStreamReader != null){
                    inputStreamReader.close();
                }

                if(fileInputStream != null){
                    fileInputStream.close();
                }

            } catch (Exception e){
                e.printStackTrace();
            }
        }
//        return list;
    }

    public static void getLinesFromFileWithTime(String filePath, List<LrcLine> list){
//        List<LrcLine> list = new ArrayList<LrcLine>();
        FileInputStream fileInputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            File file=new File(filePath);
            if(file.isFile() && file.exists()){ //判断文件是否存在
                fileInputStream = new FileInputStream(file) ;
				//Gionee <hongsq> <2016-12-23> modify for <49328> begin
                fileInputStream.markSupported();
                String ct = codeString(file);
                inputStreamReader = new InputStreamReader(fileInputStream, ct);
				//Gionee <hongsq> <2016-12-23> modify for <49328> end
                bufferedReader = new BufferedReader(inputStreamReader);
                String lineTxt = null;
                while((lineTxt = bufferedReader.readLine()) != null){
                    //list.add(lineTxt);
                    if(lineTxt.length() > 0){
                        List<String> timeList = getTimeList(lineTxt);
                        String s = lineTxt.substring(lineTxt.lastIndexOf(']')+1);
                        if(s == null || s.length() == 0) {
                            s = "";
                        }
                        s = s.trim();
                        s = getLrcWithoutTrcTag(s);
                        int i =0;
                        for(i =0; i < timeList.size(); i++){
                            String strTime = timeList.get(i);
                            long time = strToSecs(strTime);
                            long millTime = strToMillisecond(strTime);
                            if (time >= 0) {
                                LrcLine ll = new LrcLine();
//                                ll.setPos(strToSecs(timeList.get(i)));
                                Log.i("lipeineng", "i " + i + "; millTime " + millTime + "; s " + s + "; " + strTime);
                                ll.setPos(time);
                                ll.setMillPos(millTime);
                                ll.setLrcStr(s);
                                list.add(ll);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(bufferedReader != null){
                    bufferedReader.close();
                }

                if(inputStreamReader != null){
                    inputStreamReader.close();
                }

                if(fileInputStream != null){
                    fileInputStream.close();
                }

            } catch (Exception e){
                e.printStackTrace();
            }
        }
//        return list;
    }

    public static boolean getLinesFromFile(int fileId, List<LrcLine> list) {
        if (list == null) {
            return false;
        }
        boolean res = true;
        try {
            getLinesFromFileWithTime(fileId, list);
            if (list.size() == 0) {
                res = false;
            }
        } catch(Exception e) {

        }
        return res;
    }
    
    public static boolean getLinesFromFile(String filePath, List<LrcLine> list) {
        if(list == null) {
            return false;
        }
        boolean res = true;
        try {
            getLinesFromFileWithTime(filePath, list);
            if (list.size() == 0) {
                getLinesFromFileWithoutTime(filePath, list);
                res = false;
            }
        } catch(Exception e) {

        }
        return res;
    }
    
    public static void getLinesFromFileWithoutTime(String filePath, List<LrcLine> list) {
//        List<LrcLine> list = new ArrayList<LrcLine>();
        FileInputStream fileInputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            File file=new File(filePath);
            if(file.isFile() && file.exists()){ //判断文件是否存在
                fileInputStream = new FileInputStream(file) ;
                inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
                bufferedReader = new BufferedReader(inputStreamReader);
                String lineTxt = null;
                while((lineTxt = bufferedReader.readLine()) != null){
                    LrcLine ll = new LrcLine();
                    ll.setLrcStr(lineTxt);
                    ll.setPos(-1);
                    list.add(ll);                    
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(bufferedReader != null){
                    bufferedReader.close();
                }
                
                if(inputStreamReader != null){
                    inputStreamReader.close();
                }
                
                if(fileInputStream != null){
                    fileInputStream.close();
                }
                
            } catch (Exception e){
                e.printStackTrace();
            }
        }
//        return list;
        
    }
    
    public static String getLrcFilePath(String artistName, String songName){
        //Gionee <hongsq> <2016-12-10> modify for <40710> begin
        if(AppConfig.getInstance().getIsOffLine())
        {
            Context c = MyApp.getInstance().getApplicationContext();
            String DEFAULT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();

            File f = new File(DEFAULT_PATH);
            if(f.canRead())
            {
                if(FileUtil.isExist(DEFAULT_PATH + LRC_PATH_OVERSEA + "/" + songName + ".lrc")){
                    return DEFAULT_PATH + LRC_PATH_OVERSEA + "/" + songName + ".lrc";
                }
            }
            return DEFAULT_PATH + LRC_PATH_OVERSEA + "/" + songName + ".lrc";
        }
        //Gionee <hongsq> <2016-12-10> modify for <40710>  end
        return FilePathUtils.getLrcFilePath(artistName, songName);
    }
    
    public static boolean isExistLrcFile(String artistName, String songName){
        boolean res =  false;
        File file=new File(getLrcFilePath(artistName, songName));
        if(file.isFile() && file.exists())
            res = true;
        return res;
    }
    
    //Gionee <hongsq> <2016-12-10> modify for <40710> begin
    public static boolean isExistFile(String path){
        boolean res =  false;
        File file=new File(path);
        if(file.isFile() && file.exists())
            res = true;
        return res;
    }
    //Gionee <hongsq> <2016-12-10> modify for <40710>  end

    public static int getCurIndex(long pos, List<LrcLine> lines){
        int res = -1;
        try {
            if(lines == null)
                return -1;
            int size = lines.size();
            if(size <2)
                return 0;
            for(int i=1;i<size;i++){
                LrcLine ll = lines.get(i);
                LrcLine ll2 = lines.get(i -1);
                if(ll.getMillPos() >= pos && ll2.getMillPos() <= pos){
                    res = i - 1;
                }
            }
            LrcLine l = lines.get(lines.size() -1);
            if(l.getMillPos() <= pos)
                res = lines.size() -1;
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return res;
    }
    
    private static String getTiStr(String s){
        String res = null;
        int p1 = s.indexOf("[ti:");
        int p2 = s.indexOf("]");
        if(p1 >= 0 && p2 > p1){
            String s2 = s.substring(p1,p2);
            if(s2 != null && s2.length() >0){
                int p3 = s2.indexOf(":");
                if(p2 > 0){
                    res = s2.substring(p3+1);
                }
            }
        }        
        return res;
    }

    public static float getIncrement(int fileId) {
        float increment = 0;
        String lrc = "";
        try {
            lrc = getStringFromFile(fileId);

            StringTokenizer tokenizer = new StringTokenizer(lrc, CONFIG_SEPARATOR);
            if(tokenizer == null || tokenizer.countTokens() == 0) {
                return increment;
            }

            String str;

            while (tokenizer.hasMoreTokens()) {
                str = tokenizer.nextToken();
                if(!str.startsWith(PREFIX)) {
                    continue;
                }
                String tmp = str.substring(PREFIX.length(), str.length());
                Log.i("LrcUtil", "getIncrement : " + tmp);
                increment = Float.parseFloat(tmp);
                break;
            }
        } catch (Exception e) {
            Log.i("LrcUtil", e.toString());
        }

        return increment;
    }
    
    public static float getIncrement(String filePath) {
        float increment = 0;
        String lrc = "";
        try {
            lrc = getStringFromFile(filePath);

            StringTokenizer tokenizer = new StringTokenizer(lrc, CONFIG_SEPARATOR);
            if(tokenizer == null || tokenizer.countTokens() == 0) {
                return increment;
            }

            String str;

            while (tokenizer.hasMoreTokens()) {
                str = tokenizer.nextToken();
                if(!str.startsWith(PREFIX)) {
                    continue;
                }
                String tmp = str.substring(PREFIX.length(), str.length());
                Log.i("LrcUtil", "getIncrement : " + tmp);
                increment = Float.parseFloat(tmp);
                break;
            }
        } catch (Exception e) {
            Log.i("LrcUtil", e.toString());
        }

        return increment;
    }
    
//    public static void setIncrement(String filePath, float increment) {
//        String lrc = getStringFromFile(filePath);
//        if(lrc.length() == 0) {
//            return;
//        }
//
//        StringTokenizer tokenizer = new StringTokenizer(lrc, CONFIG_SEPARATOR);
//        if(tokenizer == null || tokenizer.countTokens() == 0) {
//            return;
//        }
//
//        String str = "";
//        //Gionee <hongsq> <2017-3-14> modify for <82771> begin
//        try{
//            StringBuilder newLrc = new StringBuilder();
//            File file = new File(filePath);
//            String ct = codeString(file);
//            while(tokenizer.hasMoreTokens()) {
//                str = tokenizer.nextToken();
//                if(!str.startsWith(PREFIX)) {
//                    newLrc.append(str + CONFIG_SEPARATOR);
//                    continue;
//                }
//                newLrc.append(PREFIX + increment);
//                FileUtil.writeStringToFile(newLrc.toString(), filePath,ct);
//                return;
//            }
//            newLrc.append(PREFIX + increment);
//            FileUtil.writeStringToFile(newLrc.toString(), filePath,ct);
//        }catch(Exception e)
//        {
//
//        }
//        //Gionee <hongsq> <2017-3-14> modify for <82771> end
//    }
    public static String getStringFromFile(int fileId) {
        String str = "";
        InputStream fis = null;
        try {
            fis= MyApp.getInstance().getResources().openRawResource(fileId);
            int length = fis.available();
            byte[] buffer = new byte[length];
            fis.read(buffer);
            str = new String(buffer, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("LrcUtil", e.toString());
        } finally {
            if(fis != null) {
                try {
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return str;
        }
    }

    public static String getStringFromFile(String filePath) {
        String str = "";
        FileInputStream fis = null;
        try {
            File file = new File(filePath);
            if(file.exists() && file.isFile()) {
                fis = new FileInputStream(file);
                int length = fis.available();
                byte[] buffer = new byte[length];
                fis.read(buffer);
                //Gionee <hongsq> <2017-3-14> modify for <82771> begin
                String ct = codeString(file);
                str = new String(buffer, ct);
                //Gionee <hongsq> <2017-3-14> modify for <82771> end
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("LrcUtil", e.toString());
        } finally {
            if(fis != null) {
                try {
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return str;
        }
    }
    
    private static String getLrcWithoutTrcTag(String str) {
        if(str == null) {
            return null;
        }
        String flag = "<[0-9]+>";
        String s = str.replaceAll(flag, "");
        return s;
    }
    //Gionee <hongsq> <2016-12-10> modify for <40710> begin
    public static boolean isExistLrcFile(String filename){
        boolean res =  false;
        File file=new File(getLrcFilePath(filename));
        if(file.isFile() && file.exists())
            res = true;
        return res;
    }
    public static String getLrcFilePath(String filename){



            File path = new File(DEFAULT_PATH);
            if(path.canRead())
            {
                if(FileUtil.isExist(DEFAULT_PATH + LRC_PATH_OVERSEA + "/" + filename + ".lrc")){
                    return DEFAULT_PATH + LRC_PATH_OVERSEA + "/" + filename + ".lrc";
                }
            }
        return DEFAULT_PATH + LRC_PATH_OVERSEA + "/" + filename + ".lrc";
    }
	//Gionee <hongsq> <2016-12-10> modify for <40710> end
	//Gionee <hongsq> <2016-12-23> modify for <49328> begin
    public static String codeString(File f) throws Exception {
		CodepageDetectorProxy codepageDetector = CodepageDetectorProxy.getInstance();
		codepageDetector.add(new ParsingDetector(false));
		codepageDetector.add(JChardetFacade.getInstance());
		codepageDetector.add(new ByteOrderMarkDetector());
		codepageDetector.add(ASCIIDetector.getInstance());
		codepageDetector.add(UnicodeDetector.getInstance());
		Charset charset = null;
		try {
			charset = codepageDetector.detectCodepage(f.toURI().toURL());
			if (charset != null){
				return charset.name();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "GBK";
    }
	//Gionee <hongsq> <2016-12-23> modify for <49328> end
}
//Gionee zhangjc 2013-05-15 added lrc function CR00808250 end
